/**
 * 20.1.9：移除重写的clone
 */
let THREE=require('three');
import HardLine from './hard-line';

const REF_ZERO=new THREE.Vector3(0,0,0);
const REF_X=new THREE.Vector3(1e-6,0,0);

/**
 * 顶点定长线（前面加，后面减，轨迹线）
 * 支持箭头（顶点频繁更新时会降低效率）
 *
 @param values {object} {name,value}
 color:new THREE.Color(0,1,0),  颜色
 width:0.5,  线宽
 dashSize:0.1,  虚线长
 gapSize:0.1,  虚线空白长
 perspectiveFactor:10,  透视系数
 arrowLengthRat:1,  箭头长度比值（相对虚线+空白）
 arrowWidthRat:1,  箭头宽比（相对线宽）
 arrowMode:0,  箭头模式[0:none,1:right,2:left,3:double]
 opacity:1,  透明度
 dashFill:true,  虚线还是实线
 rayCast:true,  是否开启射线检测
 sizeAttenuation:true,  是否启用近大远小
 zOffset:0,  z偏移
 maxSegments:100, 最大顶点长度

 材质通用属性可获取material进行编辑
 几何体通用属性可获取geometry进行编辑
 */
export default class traceLine extends HardLine{
    constructor(vertices=[],values={}){
        super(vertices,values);
        console.warn('this class is deprecated now !');
    }

    //------------------------------对外属性及方法--------------------------

    /**
     * 顶点
     * @returns {Array}
     */
    get vertices(){
        return this._verts;
    }

    /**
     *更新顶点
     * @param vs {Array}
     */
    set vertices(vs){
        let start=Math.max(vs.length-this._maxSegments,0);
        this._verts=vs.slice(start);
        this.updateGeometry();
    }

    /**
     * 最大节点数
     * @returns {*}
     */
    get maxSegments(){
        return this._props.maxSegments.value;
    }
    set maxSegments(num){
        this._props.maxSegments.value=num;
    }

    /**
     * 添加点
     * @param v
     */
    push(v) {
        this._verts.push(v);
        this.updateGeometry();
    }

    /**
     * 清除点
     */
    clear() {
        this.verts = [REF_ZERO,REF_X];
        let s = this._maxSegments;
        let s3 = (2 * s - 3) * 6 * 3;
        let s1 = (2 * s - 3) * 6;
        this._positions = new Float32Array(s3);
        this._nextPositions = new Float32Array(s3);
        this._offsets = new Float32Array(s1);
        this._distances = new Float32Array(s1);
        this._dashMarks = new Float32Array(s1);
        this.updateGeometry();
    }

    //----------------------------------私有属性及方法----------------------------

    _initProps() {
        super._initProps();
        this._props.add({
            maxSegments:this._values.maxSegments||100,
        });
    }
    _initPropCallback() {
        super._initPropCallback();
        this._props.onKeyChange('maxSegments',(_new,_old)=>{
            this._maxSegments=_new;
            let start=Math.max(this._verts.length-_new,0);
            this._verts=this._verts.slice(start);
            this.updateGeometry();
        });
    }
    _initVariable() {
        super._initVariable();
        this._maxSegments=this._props.maxSegments.value;
        let s=this._maxSegments;
        let s3=(2*s-3)*6*3;
        let s1=(2*s-3)*6;
        this._positions=new Float32Array(s3);
        this._nextPositions=new Float32Array(s3);
        this._offsets=new Int8Array(s1);
        this._distances=new Float32Array(s1);
        this._dashMarks=new Uint8Array(s1);
    }

    _rectifyPoints(ps) {
        switch (this._props.arrowMode.value) {
            case 0:
                this.arrowWidth=0;
                this.arrowLength=0;
                return ps;
            case 1:
                return this._rectifyRightArrowPoints(ps);
            case 2:
                return this._rectifyLeftArrowPoints(ps);
            case 3:
                return this._rectifyDoubleArrowPoints(ps);
        }
    }
    _reRangeData(){
        if (this._rectifyVerts.length>this._maxSegments) {
            this._verts.splice(0,1);
            this._positions.copyWithin(0,18*2);
            this._nextPositions.copyWithin(0,18*2);
            this._offsets.copyWithin(0,6*2);
            this._distances.copyWithin(0,6*2);
            this._dashMarks.copyWithin(0,6*2);
        }
    }
}
